using System;
using System.Collections.Generic;
using System.Data;
using AntJoin.Dapper.Query;
using System.Linq;
using System.Threading.Tasks;

namespace AntJoin.Dapper
{
    public interface IDao
    {
        ConnectionManager ConnectionManager { get; }
        IDbTransaction TxBegin();
        IDbTransaction TxBegin(IsolationLevel il);
        void TxCommit();
        void TxRollback();
        IDbConnection Open();
        /// <summary>
        /// close connection and commit transaction
        /// </summary>
        void Close();

        //------------------QUERY / EXECUTE----------------------------------
        /// <param name="sql"></param>
        /// <param name="param">IEnumerable for multiExec</param>
        int Execute(string sql, object param);
        int Execute(QueryInfo info);
        T ExecuteScalar<T>(string sql, object param);

        int QueryCount(QueryInfo info);
        IEnumerable<T> Query<T>(string sql, object param);
        IEnumerable<object> Query(string sql, object param, Type type);
        IEnumerable<T> Query<T>(QueryInfo info);

        /// <summary>
        /// TotalCount==1 ʱ�����ظ�����ҳ������
        /// info.MappingType=null�������ֵ�
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        IEnumerable<object> Query(QueryInfo info);
        DataTable QueryDataTable(string sql, object param);

        string BuildPagingSQL(QueryInfo info);

        /// <summary>
        /// ����TotalCount=1,���Զ�SQL�����ɷ�ҳ��ѯ������+��¼��
        /// info.MappingType ��ʱ��������
        /// </summary>
        QueryInfo QueryPaginate(QueryInfo info);

        /// <summary>
        /// TotalCount=1时，执行 分页查询+总数
        /// </summary>
        QueryInfo<T> QueryPaginate<T>(QueryInfo<T> info);


        /// <summary>
        /// 查询第一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        T QueryFirst<T>(string sql, object param);

        /// <summary>
        /// 查询第一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        T QueryFirst<T>(QueryInfo info);

        /// <summary>
        /// 查询第一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        T QueryFirstOrDefault<T>(string sql, object param);


        /// <summary>
        /// 查询第一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        T QueryFirstOrDefault<T>(QueryInfo info);

        /// <summary>
        /// 查询唯一一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        T QuerySingle<T>(string sql, object param);

        /// <summary>
        /// 查询唯一一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        T QuerySingle<T>(QueryInfo info);

        /// <summary>
        /// 查询唯一一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        T QuerySingleOrDefault<T>(string sql, object param);


        /// <summary>
        /// 查询唯一一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        T QuerySingleOrDefault<T>(QueryInfo info);



        #region 异步方法
        /// <summary>
        /// 执行语句
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<int> ExecuteAsync(string sql, object param);

        /// <summary>
        /// 执行语句
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<int> ExecuteAsync(QueryInfo info);


        /// <summary>
        /// 查询数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<T> ExecuteScalarAsync<T>(string sql, object param);


        /// <summary>
        /// 查询数量
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<int> QueryCountAsync(QueryInfo info);


        /// <summary>
        /// 查询数据列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<IEnumerable<T>> QueryAsync<T>(string sql, object param);


        /// <summary>
        /// 查询数据列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<IEnumerable<T>> QueryAsync<T>(QueryInfo info);


        /// <summary>
        /// 查询数据列表
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        Task<IEnumerable<object>> QueryAsync(string sql, object param, Type type);


        /// <summary>
        /// 查询数据列表
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<IEnumerable<object>> QueryAsync(QueryInfo info);

        /// <summary>
        /// 查询分页数据， TotalCount=1时，执行 分页查询+总数
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<QueryInfo> QueryPaginateAsync(QueryInfo info);

        /// <summary>
        /// 查询分页数据， TotalCount=1时，执行 分页查询+总数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<QueryInfo<T>> QueryPaginateAsync<T>(QueryInfo<T> info);



        /// <summary>
        /// 查询第一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<T> QueryFirstAsync<T>(string sql, object param);

        /// <summary>
        /// 查询第一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<T> QueryFirstAsync<T>(QueryInfo info);

        /// <summary>
        /// 查询第一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<T> QueryFirstOrDefaultAsync<T>(string sql, object param);


        /// <summary>
        /// 查询第一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<T> QueryFirstOrDefaultAsync<T>(QueryInfo info);

        /// <summary>
        /// 查询唯一一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<T> QuerySingleAsync<T>(string sql, object param);

        /// <summary>
        /// 查询唯一一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<T> QuerySingleAsync<T>(QueryInfo info);

        /// <summary>
        /// 查询唯一一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Task<T> QuerySingleOrDefaultAsync<T>(string sql, object param);


        /// <summary>
        /// 查询唯一一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        Task<T> QuerySingleOrDefaultAsync<T>(QueryInfo info);

        #endregion
    }
}
